<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Calendar extends MY_Controller
{
  const BACK_DEFAULT = '#336600';
  const TEXT_DEFAULT = '#ffffff';
  const BACK_ONE_LEFT = '#cc3333';
  const TEXT_ONE_LEFT = '#ffffff';
  const BACK_TWO_LEFT = '#cccc00';
  const TEXT_TWO_LEFT = '#000000';
  const BACK_FIRST_LESSON = '#6699ff';
  const TEXT_FIRST_LESSON = '#000000';
  const BACK_CANCELED_OVER_24 = '#ababab';
  const TEXT_CANCELED_OVER_24 = '#000';
  const BACK_FIRST_LESSON_UNPAID = '#efefef';
  const TEXT_FIRST_LESSON_UNPAID = '#aa0000';

  function __construct()
  {
    parent::__construct();

    $this->load->model('event_model');
    $this->load->model('product_model');
    $this->load->model('user_model');
    $this->load->model('studio_model');
    $this->load->model('schedule_model');
    $this->load->model('note_model');
    $this->load->model('reason_model');
    $this->load->model('delete_reason_model');
    $this->load->library('form_validation');
    $this->load->library('typography');
    $this->load->model('email_admin_reason');
  }

  function event($eid_cid = null, $op = 'add')
  {
    $this->permission_model->check_permission($this->user->uid, 'manage event');

    $title = 'Add event';
    if($eid_cid)
    {
      $title = 'Edit lesson';
    }

    switch($op)
    {
      case 'save':
        if(empty($eid_cid))
        {
          $this->form_validation->set_rules('name', 'Name', 'required');
          $this->form_validation->set_rules('student', 'Student', 'required');
          $this->form_validation->set_rules('teacher', 'Teacher', 'required');
          $this->form_validation->set_rules('product', 'Product', 'required');
          $this->form_validation->set_rules('studio', 'Studio', 'required');
          $this->form_validation->set_rules('scheduled_date', 'Date', 'required|callback_date_time_check');
          $this->form_validation->set_rules('scheduled_time_from', 'From', 'required');
          $from = $this->input->post('scheduled_time_from');
          $this->form_validation->set_rules('scheduled_time_to', 'To', 'required|greater_than[' . $from . ']');

          if($this->form_validation->run() !== false)
          {
            // validation pass
            $event = (object)array(
              'name' => $this->input->post('name'),
              'student_id' => $this->input->post('student'),
              'product_id' => $this->input->post('product'),
              'description' => $this->input->post('description'),
              'status' => Event_model::STATUS_UNPAID,
              'created' => time(),
            );

            // fetching necessary objects
            $event->student = $this->user_model->student_info($event->student_id);
            $event->product = $this->product_model->products($event->product_id);

            // calculating scheduled date/time
            $scheduled_date = $this->input->post('scheduled_date');
            $scheduled_time_from = time_value($this->input->post('scheduled_time_from'));
            $scheduled_time_to = time_value($this->input->post('scheduled_time_to'));
            $scheduled_date_arr = explode('/', $scheduled_date);

            $start_scheduled = strtotime("$scheduled_date_arr[2]-$scheduled_date_arr[1]-$scheduled_date_arr[0] $scheduled_time_from");
            $start_ended = strtotime("$scheduled_date_arr[2]-$scheduled_date_arr[1]-$scheduled_date_arr[0] $scheduled_time_to");

            // generating schedules
            $product = $event->product;
            for($i = 0; $i < $product->lessons; $i++)
            {
              $weeks = $i * $event->product->recurring;
              $event->schedules[] = (object)array(
                'sequence' => $i+1,
                'start' => strtotime("+{$weeks} weeks", $start_scheduled),
                'end' => strtotime("+{$weeks} weeks", $start_ended),
                'status' => schedule_model::STATUS_PENDING,
                'staff_id' => $this->input->post('teacher'),
                'studio_id' => $this->input->post('studio'),
              );
            }

            // checking if each of schedule is valid
            $valid_schedules = TRUE;
            $errors = array();
            foreach($event->schedules as $schedule)
            {
              $schedule->event = $event;
              if ( ! $this->schedule_model->is_valid($schedule))
              {
                $valid_schedules = FALSE;
                $errors[] = '<p>System detects schedule of lesson #' . $schedule->sequence  . '
              conflicts with schedule of other lesson by the same teacher. Please double check the calendar.</p>';
              }
            }

            if ( ! $valid_schedules)
            {
              $this->data['error'] = implode('', $errors);
            }
            else
            {
              $this->event_model->save($event);

              // send mail
              $mail = $this->input->post('email_notification');
              if($mail)
              {
                $this->_send_mail_student($event);
              }

              $this->session->set_flashdata('message', 'Event and its schedules has been created.');

              redirect('calendar?view=agendaWeek&start=' . $start_scheduled);
            }
          }
        }
        else
        {
          $this->form_validation->set_rules('name', 'Name', 'required');
          $this->form_validation->set_rules('teacher', 'Teacher', 'required');
          $this->form_validation->set_rules('studio', 'Studio', 'required');

          if($this->form_validation->run() !== false)
          {
            list($eid, $cid) = explode('_', $eid_cid);
            $event = $this->event_model->events($eid);
            $event->name = $this->input->post('name');
            $event->description = $this->input->post('description');

            // save event
            $this->event_model->save($event);

            // edited schedule
            $edited_schedules = array();
            $edited_schedule = $this->schedule_model->schedules($cid);

            if($this->input->post('all_lessons') == 'all')
            {
              // get all schedules of the event
              $event->schedules = $this->schedule_model->event_schedules($eid);
              foreach($event->schedules as $schedule)
              {
                if($schedule->sequence >= $edited_schedule->sequence &&
                  $schedule->status == Schedule_model::STATUS_PENDING)
                {
                  $schedule->staff_id = $this->input->post('teacher');
                  $schedule->studio_id = $this->input->post('studio');
                  $this->schedule_model->save($schedule);
                  $edited_schedules[] = $schedule;
                }
              }
            }
            else
            {
              $edited_schedule->staff_id = $this->input->post('teacher');
              $edited_schedule->studio_id = $this->input->post('studio');
              $this->schedule_model->save($edited_schedule);
              $edited_schedules[] = $edited_schedule;
            }

            // send mail
            $mail = $this->input->post('email_notification');
            if($mail)
            {
              $this->_edit_lessons_send_mail_student($event, $edited_schedules);
            }
            $this->session->set_flashdata('message', 'Lesson has been updated.');
            redirect('calendar');
          }
        }

        break;
    }

    if( ! empty($_GET['sid']))
    {
      $default_student = $this->user_model->student_info($_GET['sid']);
      $this->data['default_student'] = $default_student;
    }

    $product_options = array('' => 'Please select') + $this->product_model->list_options();
    $teacher_options = array('' => 'Please select') + $this->user_model->list_options();
    $studio_options = array('' => 'Please select') + $this->studio_model->list_options();

    $event = $this->event_model->prepare_empty_event();
    if($eid_cid)
    {
      list($eid, $cid) = explode('_', $eid_cid);

      $event = $this->event_model->events($eid);
      if( ! $event)
      {
        page_not_found();
      }

      $event->student = $this->user_model->student_info($event->student_id);
      $event->product = $this->product_model->products($event->product_id);
      $event->schedule = $this->schedule_model->schedules($cid);
    }

    // assets
    $this->add_asset('js/vendor/jquery-ui-1.9.2.custom/js/jquery-ui-1.9.2.custom.min.js');
    $this->add_asset('js/vendor/jquery-ui-1.9.2.custom/css/smoothness/jquery-ui-1.9.2.custom.min.css', 'css');
    $this->add_asset('js/events.js');

    // data
    $this->data = array_merge($this->data,
      array(
        'title' => $title,
        'template' => 'event',
        'event' => $event,
        'product_options' => $product_options,
        'teacher_options' => $teacher_options,
        'studio_options' => $studio_options,
      )
    );

    $this->render_page();
  }

  function date_time_check()
  {
    $scheduled_date = $this->input->post('scheduled_date');
    $scheduled_time_from = time_value($this->input->post('scheduled_time_from'));
    $scheduled_time_to = time_value($this->input->post('scheduled_time_to'));
    $scheduled_date_arr = explode('/', $scheduled_date);

    $start_scheduled = strtotime("$scheduled_date_arr[2]-$scheduled_date_arr[1]-$scheduled_date_arr[0] $scheduled_time_from");
    $start_ended = strtotime("$scheduled_date_arr[2]-$scheduled_date_arr[1]-$scheduled_date_arr[0] $scheduled_time_to");

    if($start_scheduled >= $start_ended)
    {
      $this->form_validation->set_message('date_time_check', '"From" time must be greater than "to" time.');
      return FALSE;
    }

    return TRUE;
  }

  function reset_filter()
  {
    $this->session->unset_userdata(array(
      'studio_id_filter' => '',
      'teacher_id_filter' => ''
    ));

    redirect('calendar');
  }

  function index()
  {
    $this->permission_model->check_permission($this->user->uid, 'view calendar');

    // assets
    $this->add_asset('js/vendor/jquery-ui-1.9.2.custom/js/jquery-ui-1.9.2.custom.min.js');
    $this->add_asset('js/vendor/jquery-ui-1.9.2.custom/css/smoothness/jquery-ui-1.9.2.custom.min.css', 'css');
    $this->add_asset('js/vendor/fullcalendar-1.5.4/fullcalendar/fullcalendar.css', 'css');
    $this->add_asset('js/vendor/fullcalendar-1.5.4/fullcalendar/fullcalendar.print.css', 'print_css');
    $this->add_asset('js/vendor/fullcalendar-1.5.4/fullcalendar/fullcalendar.min.js');
    $this->add_asset('js/vendor/jquery.qtip-1.0.0-rc3.min.js');
    $this->add_asset('js/vendor/jquery.blockUI.js');
    $this->add_asset('js/events.js');
    $this->add_asset('js/calendar.js?20130509');

    $this->add_asset('$.extend(VSACRM, {
      studio_start_time: ' . $this->config->item('studio_start_time') . ',
      studio_end_time: ' . $this->config->item('studio_end_time') . '});', 'inline_js');

    if( ! empty($_GET['view']) &&
      ! empty($_GET['start'])) {
      $this->add_asset('$.extend(VSACRM, {
      current_calendar_view: "' . $_GET['view'] . '",
      current_calendar_start: ' . $_GET['start'] . '});', 'inline_js');
    }

    if($_POST)
    {
      // add to session
      $this->session->set_userdata(array(
        'studio_id_filter' => $this->input->post('studio_id') ? $this->input->post('studio_id') : '',
        'teacher_id_filter' => $this->input->post('teacher_id') ? $this->input->post('teacher_id') : ''
      ));
    }

    $studio_id_filter = $this->session->userdata('studio_id_filter');
    $teacher_id_filter = $this->session->userdata('teacher_id_filter');

    $this->add_asset('$.extend(VSACRM, {
      studio_id: "' . $studio_id_filter . '",
      teacher_id: "' . $teacher_id_filter . '"
      });', 'inline_js');

    // detect teacher view
    $view = 'admin';
    if(count($this->user->roles) == 1 && array_shift(array_values($this->user->roles)) == 'teacher')
    {
      $this->add_asset('$.extend(VSACRM, {
      teacher_id: ' . $this->user->uid .
        '});', 'inline_js');
      $view = 'teacher';
    }
    // pass $view into js
    $this->add_asset("$.extend(VSACRM, {view: '$view'});", 'inline_js');

    $schedule_statuses = $this->schedule_model->status_options();
    $this->add_asset("$.extend(VSACRM, {schedule_statuses: " . json_encode($schedule_statuses) . "});", 'inline_js');

    $title = 'Calendar';
    $product_options = $this->product_model->list_options();
    $this->data = array(
      'title' => $title,
      'template' => 'calendar',
      'view' => $view,
      'product_options' => $product_options,
      'user' => $this->user
    );

    $this->render_page();
  }

  function json()
  {
    $start = $_GET['start'];
    $end = $_GET['end'];

    $this->load->library('output');
    $studio_id = $teacher_id = null;

    if ( ! empty($_GET['studio_id']))
    {
      $studio_id = $_GET['studio_id'];
    }
    if ( ! empty($_GET['teacher_id']))
    {
      $teacher_id = $_GET['teacher_id'];
    }

    // fetch schedules & pass to js
    $schedules = array();
    if (empty($studio_id) && empty($teacher_id))
    {
      $schedules = $this->schedule_model->query(array(
        'start' => $start,
        'end' => $end,
        'filter' => '*'
      ));
    }
    else if ( ! empty($studio_id) && empty($teacher_id))
    {
      $schedules = $this->schedule_model->query(array(
        'start' => $start,
        'end' => $end,
        'filter' => 'studio',
        'ids' => array(
          'studio_id' => $studio_id,
        )
      ));
    }
    else if ( ! empty($teacher_id) && empty($studio_id))
    {
      $schedules = $this->schedule_model->query(array(
        'start' => $start,
        'end' => $end,
        'filter' => 'teacher',
        'ids' => array(
          'teacher_id' => $teacher_id,
        )
      ));
    }
    else
    {
      $schedules = $this->schedule_model->query(array(
        'start' => $start,
        'end' => $end,
        'filter' => 'studio_teacher',
        'ids' => array(
          'studio_id' => $studio_id,
          'teacher_id' => $teacher_id,
        )
      ));
    }

    // fetching title for each schedule
    static $events = array();
    foreach($schedules as $key => $schedule)
    {
      if (empty($events[$schedule->eid]))
      {
        $event = $this->event_model->events($schedule->eid);
        $event->description = $event->description;
        $event->student = $this->user_model->student_info($event->student_id);
        $event->product = $this->product_model->products($event->product_id);
        $events[$schedule->eid] = $event;
      }

      $schedules[$key]->teacher = $this->user_model->staff_info($schedules[$key]->staff_id);
      $schedules[$key]->studio = $this->studio_model->studios($schedules[$key]->studio_id);
      $schedules[$key]->event = $events[$schedule->eid];
    }

    $events = $this->_prepare_events($schedules);

    $this->output
      ->set_content_type('application/json')
      ->set_output(json_encode($events));
  }

  function schedule($op, $cid)
  {
    $calendar_view = array(
      'view' => 'agendaWeek',
      'start' => time()
    );

    if( ! empty($_POST['current_calendar_view']) &&
      ! empty($_POST['current_calendar_start'])) {
      $calendar_view = array(
        'view' => $_POST['current_calendar_view'],
        'start' => $_POST['current_calendar_start']
      );
    }

    switch($op)
    {
      case 'status':
        // handling re-schedule for cancel over 24 hours
        if($this->input->post('status') == Schedule_model::STATUS_CANCELED_OVER_24)
        {
          $this->form_validation->set_rules('scheduled_date', 'Date', 'required|callback_date_time_check');
          $this->form_validation->set_rules('scheduled_time_from', 'From', 'required');
          $from = $this->input->post('scheduled_time_from');
          $this->form_validation->set_rules('scheduled_time_to', 'To', 'required|greater_than[' . $from . ']');

          if($this->form_validation->run() !== false)
          {
            // calculating scheduled date/time
            $scheduled_date = $this->input->post('scheduled_date');
            $scheduled_time_from = time_value($this->input->post('scheduled_time_from'));
            $scheduled_time_to = time_value($this->input->post('scheduled_time_to'));
            $scheduled_date_arr = explode('/', $scheduled_date);

            $start_scheduled = strtotime("$scheduled_date_arr[2]-$scheduled_date_arr[1]-$scheduled_date_arr[0] $scheduled_time_from");
            $start_ended = strtotime("$scheduled_date_arr[2]-$scheduled_date_arr[1]-$scheduled_date_arr[0] $scheduled_time_to");

            // old sequence (cancelled sequence)
            $old_schedule = $this->schedule_model->schedules($cid);

            // getting eid
            $result = $this->db->query('SELECT eid FROM schedules WHERE cid = ?', array($cid))->row();
            $eid = $result->eid;

            // new schedule
            $new_schedule = (object)array(
              'start' => $start_scheduled,
              'end' => $start_ended,
              'status' => Schedule_model::STATUS_PENDING,
              'eid' => $eid,
              'staff_id' => $old_schedule->staff_id,
              'studio_id' => $old_schedule->studio_id,
            );

            // checking if new schedule is valid
            $valid_schedules = TRUE;
            $errors = array();
            $event = $this->event_model->events($eid);
            $new_schedule->event = $event;
            if ( ! $this->schedule_model->is_valid($new_schedule))
            {
              $valid_schedules = FALSE;
              $errors[] = '<p>System detects schedule of lesson #' . $new_schedule->sequence  . '
            conflicts with schedule of other lesson by the same teacher. Please double check the calendar.</p>';
            }

            if ( ! $valid_schedules)
            {
              $this->session->set_flashdata('error',implode('', $errors));
            }
            else
            {
              // update old schedule
              $old_schedule->status = $this->input->post('status');
              $old_schedule->description = $this->input->post('description');
              $old_schedule->sequence = 0;
              $this->schedule_model->save($old_schedule);

              // append new schedule, rework schedule sequence
              $this->schedule_model->rework_schedules_sequence($new_schedule, $eid);

              $this->session->set_flashdata('message', 'Lesson status has been updated. A new lesson has been set. Start: ' .
                date('d/m/Y g:ia', $new_schedule->start) . ' - End: ' . date('d/m/Y g:ia', $new_schedule->end));

              // send mail
              $mail = $this->input->post('email_notification_1');
              if($mail)
              {
                $event->teacher = $this->user_model->staff_info($old_schedule->staff_id);
                $event->student = $this->user_model->student_info($event->student_id);
                $this->_cancel_mail_student($event, $old_schedule, $new_schedule);
              }
            }
          }
          else
          {
            $this->session->set_flashdata('error', validation_errors());
          }
        }
        // handling re-schedule for cancel within 24 hours
        else if($this->input->post('status') == Schedule_model::STATUS_CANCELED_IN_24)
        {
          $schedule = $this->schedule_model->schedules($cid);
          $schedule->status = $this->input->post('status');
          $schedule->description = $this->input->post('description_1');
          $this->schedule_model->save($schedule);

          $this->session->set_flashdata('message', 'Lesson status has been updated.');

          // send mail
          $mail = $this->input->post('email_notification_2');
          if($mail)
          {
            $event = $this->event_model->events($schedule->eid);
            $event->student = $this->user_model->student_info($event->student_id);
            $this->_cancel_under24_mail_student($event, $schedule);
          }
        }
        // handling for deleting event
        else if($this->input->post('status') == Schedule_model::STATUS_DELETED)
        {
          $this->form_validation->set_rules('description_2', 'Reason', 'required');

          if($this->form_validation->run() !== false)
          {
            $schedule = $this->schedule_model->schedules($cid);
            $eid = $schedule->eid;
            $this->event_model->delete($eid, $this->input->post('description_2'));

            // send mail
            $mail = $this->input->post('email_notification_3');
            if($mail)
            {
              $event = $this->event_model->events($eid);
              $event->teacher = $this->user_model->staff_info($schedule->staff_id);
              $event->student = $this->user_model->student_info($event->student_id);
              $event->product = $this->product_model->products($event->product_id);
              $this->_delete_mail_student($event);
            }

            $this->session->set_flashdata('message', 'Event has been deleted.');
          }
          else
          {
            $this->session->set_flashdata('error', validation_errors());
          }
        }
        else if($this->input->post('status') == 'rebook')
        {
          $this->form_validation->set_rules('product', 'Product', 'required');
          $this->form_validation->set_rules('rebook_date', 'Date', 'required|callback_date_time_check');
          $this->form_validation->set_rules('rebook_time_from', 'From', 'required');
          $from = $this->input->post('rebook_time_from');
          $this->form_validation->set_rules('rebook_time_to', 'To', 'required|greater_than[' . $from . ']');

          // validation pass
          if($this->form_validation->run() !== false)
          {
            // getting eid
            $result = $this->db->query('SELECT eid FROM schedules WHERE cid = ?', array($cid))->row();
            $eid = $result->eid;

            $original_event = $this->event_model->events($eid);
            $event = (object)array(
              'name' => $original_event->name,
              //'staff_id' => $original_event->staff_id,
              'student_id' => $original_event->student_id,
              //'studio_id' => $original_event->studio_id,
              'product_id' => $this->input->post('product'),
              'description' => $original_event->description,
              'status' => Event_model::STATUS_UNPAID,
              'created' => time(),
            );

            // fetching necessary objects
            $event->student = $this->user_model->student_info($event->student_id);
            $event->product = $this->product_model->products($event->product_id);

            // calculating scheduled date/time
            $scheduled_date = $this->input->post('rebook_date');
            $scheduled_time_from = time_value($this->input->post('rebook_time_from'));
            $scheduled_time_to = time_value($this->input->post('rebook_time_to'));
            $scheduled_date_arr = explode('/', $scheduled_date);

            $start_scheduled = strtotime("$scheduled_date_arr[2]-$scheduled_date_arr[1]-$scheduled_date_arr[0] $scheduled_time_from");
            $start_ended = strtotime("$scheduled_date_arr[2]-$scheduled_date_arr[1]-$scheduled_date_arr[0] $scheduled_time_to");

            // generating schedules
            $product = $event->product;
            $old_schedule = $this->schedule_model->schedules($cid);
            for($i = 0; $i < $product->lessons; $i++)
            {
              $weeks = $i * $event->product->recurring;
              $event->schedules[] = (object)array(
                'sequence' => $i+1,
                'start' => strtotime("+{$weeks} weeks", $start_scheduled),
                'end' => strtotime("+{$weeks} weeks", $start_ended),
                'status' => schedule_model::STATUS_PENDING,
                'staff_id' => $old_schedule->staff_id,
                'studio_id' => $old_schedule->studio_id,
              );
            }

            // checking if each of schedule is valid
            $valid_schedules = TRUE;
            $errors = array();
            foreach($event->schedules as $schedule)
            {
              $schedule->event = $event;
              if ( ! $this->schedule_model->is_valid($schedule))
              {
                $valid_schedules = FALSE;
                $errors[] = '<p>System detects schedule of lesson #' . $schedule->sequence  . '
              conflicts with schedule of other lesson by the same teacher. Please double check the calendar.</p>';
              }
            }

            if ( ! $valid_schedules)
            {
              $this->session->set_flashdata('error',implode('', $errors));
            }
            else
            {
              $this->event_model->save($event);

              // send mail
              $mail = $this->input->post('email_notification_4');
              if($mail)
              {
                // send mails
                $this->_send_mail_student($event);
              }

              $this->session->set_flashdata('message', 'Event and its schedules has been created.');

              if(empty($calendar_view))
              {
                redirect('calendar', 'refresh');
              }
              else
              {
                redirect("calendar?view={$calendar_view['view']}&start={$calendar_view['start']}", 'refresh');
              }
            }
          }
        }
        break;

      case 'reschedule':
        if( ! empty($_GET['current_calendar_view']) &&
          ! empty($_GET['current_calendar_start'])) {
          $calendar_view = array(
            'view' => $_GET['current_calendar_view'],
            'start' => $_GET['current_calendar_start']
          );
        }

        $start = null;
        $end = null;
        $mail = false;
        $whole_event = false;

        if( ! empty($_GET['start']))
        {
          $start = $_GET['start'];
        }
        else
        {
          $this->session->set_flashdata('error', 'Lesson cannot be re-scheduled because it does not have start time.');
        }

        if( ! empty($_GET['end']))
        {
          $end = $_GET['end'];
        }
        else
        {
          $this->session->set_flashdata('error', 'Lesson cannot be re-scheduled because it does not have end time.');
        }

        if( ! empty($_GET['mail']))
        {
          $mail = $_GET['mail'];
        }

        if( ! empty($_GET['whole_event']))
        {
          $whole_event = $_GET['whole_event'];
        }

        $schedules = array();

        // old schedules
        $old_schedules = array();
        $old_schedule = $this->schedule_model->schedules($cid);
        $old_schedules[] = $old_schedule;

        $schedule = $old_schedule;
        $schedule->start = $start;
        $schedule->end = $end;
        $schedules[] = $schedule;

        // get event
        $result = $this->db->query('SELECT eid FROM schedules WHERE cid = ?', array($cid))->row();
        $eid = $result->eid;
        $event = $this->event_model->events($eid);
        $schedule->event = $event;

        // handling rescheduling whole event
        if($whole_event)
        {
          $old_schedules = array();

          // related schedules
          $result = $this->db->query('SELECT * FROM schedules WHERE eid = ? AND start > ? AND status = ? AND cid != ?',
          array($eid, $start, Schedule_model::STATUS_PENDING, $cid))->result();

          foreach($result as $_schedule)
          {
            $old_schedules[] = $_schedule;
            // week diff
            $weeks = round(($_schedule->start - $schedules[0]->start) / (86400 * 7));
            $_schedule->start = strtotime("+$weeks weeks", $schedules[0]->start);
            $_schedule->end = strtotime("+$weeks weeks", $schedules[0]->end);
            $_schedule->event = $event;
            $schedules[] = $_schedule;
          }
        }

        $mails_to_notify = array();
        // validate this schedule
        foreach($schedules as $schedule)
        {
          if($this->schedule_model->is_valid($schedule))
          {
            $this->schedule_model->save($schedule);
            $this->session->set_flashdata('message', 'Lesson has been re-scheduled.');

            $mails_to_notify[] = $schedule;
          }
          else
          {
            $this->session->set_flashdata('error', 'Lesson #' . $schedule->sequence . ' cannot be re-scheduled because it conflicts another lesson with same teacher.');
          }
        }

        // send mail
        if($mail && ! empty($mails_to_notify))
        {
          $event->teacher = $this->user_model->staff_info($old_schedule->staff_id);
          $event->student = $this->user_model->student_info($event->student_id);
          $this->_reschedule_mail_student($event, $mails_to_notify, $old_schedules);
        }

        break;

      case 'mark-paid':
        if( ! empty($_GET['current_calendar_view']) &&
          ! empty($_GET['current_calendar_start'])) {
          $calendar_view = array(
            'view' => $_GET['current_calendar_view'],
            'start' => $_GET['current_calendar_start']
          );
        }

        // for this case $cid is $eid
        $eid = $cid;
        $this->event_model->save((object) array(
          'eid' => $eid,
          'status' => Event_model::STATUS_ACTIVE,
        ));
        break;
    }

    if(empty($calendar_view))
    {
      redirect('calendar', 'refresh');
    }
    else
    {
      redirect("calendar?view={$calendar_view['view']}&start={$calendar_view['start']}", 'refresh');
    }
  }

  private function _prepare_events($schedules)
  {
    // populate events
    $events = array();
    $timezoneOffset = 0;

    if( ! empty($schedules))
    {
      foreach($schedules as $i => $schedule)
      {
        $student = $schedule->event->student;
        $product = $schedule->event->product;
        $studio = $schedule->studio;
        $teacher = $schedule->teacher;

        // prevent calendar not displaying correctly if those data failed to load
        if(empty($product) || empty($student) || empty($teacher) || empty($studio)) {
          continue;
        }

        $lessons = intval($product->lessons);
        $sequence = intval($schedule->sequence);

        if($schedule->sequence == 0) {
          $descriptionTitle = $schedule->event->name;
        } else {
          $descriptionTitle = $schedule->event->name . ' <em>(lesson: ' . $schedule->sequence . ' of ' . $lessons . ')</em>';
        }

        $description = '<ul class="unstyled">';
        $description .= '<li><strong>Teacher: </strong>';
        $description .= $teacher->first_name . ' ' . $teacher->last_name . ' <em>(' . $teacher->mail . ')</em>';
        $description .= '</li>';
        $description .= '<li><strong>Student: </strong>';
        $description .= $student->first_name . ' ' . $student->last_name . '<br /><em>(e: ' . $student->mail . ', m: ' . $student->mobile . ')</em>';
        $description .= '</li>';
        $description .= '<li><strong>Package: </strong>' . $product->name . ' <em>(' . $product->lessons . ' lessons)</em></li>';
        $description .= '<li><strong>Studio: </strong>' . $studio->name . '</li>';
        $description .= '<li><strong>Status: </strong>' . $this->schedule_model->status($schedule->status) . '</li>';
        $description .= '</ul>';

        // calculating color scheme
        $colors = (object)array(
          'back' => self::BACK_DEFAULT,
          'text' => self::TEXT_DEFAULT
        );

        // calculate rebook
        $schedule->rebook = FALSE;

        switch($lessons - $sequence) {
          case 0: // 1 lesson left: RED background
            $colors = (object)array(
              'back' => self::BACK_ONE_LEFT,
              'text' => self::TEXT_ONE_LEFT
            );
            $schedule->rebook = TRUE;
            break;
          case 1: // 2 lessons left: YELLOW background
            $colors = (object)array(
              'back' => self::BACK_TWO_LEFT,
              'text' => self::TEXT_TWO_LEFT
            );
            break;
          case ($lessons - 1): // first lesson: BLUE background
            $colors = (object)array(
              'back' => self::BACK_FIRST_LESSON,
              'text' => self::TEXT_FIRST_LESSON
            );
            break;
        }

        // checking unpaid event
        if($lessons - $sequence == $lessons - 1)
        {
          if($schedule->event->status == Event_model::STATUS_UNPAID)
          {
            $colors = (object)array(
              'back' => self::BACK_FIRST_LESSON_UNPAID,
              'text' => self::TEXT_FIRST_LESSON_UNPAID,
            );
            $schedule->unpaid = TRUE;
          }
        }

        if($schedule->status == Schedule_model::STATUS_CANCELED_OVER_24)
        {
          $colors = (object)array(
            'back' => self::BACK_CANCELED_OVER_24,
            'text' => self::TEXT_CANCELED_OVER_24
          );
        }

        // calculating last schedule in the event, using for CANCEL OVER 24
        $result = $this->db->query("SELECT start FROM schedules WHERE eid = ? ORDER BY cid DESC LIMIT 0, 1", array(
          $schedule->event->eid
        ))->row();
        $schedule->calculated_cancel_over_24_time = strtotime('+1 week', $result->start);

        // note history
        $schedule->note_history = $this->note_model->note_history($student->sid);
        $event = (object)array(
          'id' => $schedule->cid,
          'title' => $schedule->event->name,
          'start' => $schedule->start + $timezoneOffset,
          'end' => $schedule->end + $timezoneOffset,
          'allDay' => false,
          'className' => array('event-popover'),
          'description' => '<small><h6>' . $descriptionTitle . '</h6>' . $description . '</small>',
          'schedule' => $schedule,
          'textColor' => $colors->text,
          'backgroundColor' => $colors->back,
          'borderColor' => '#333333',
          'editable' => $schedule->status == Schedule_model::STATUS_PENDING ? TRUE : FALSE,
        );

        $events[] = $event;
      }
    }

    return $events;
  }

  private function _delete_mail_student($event)
  {
    $student = $event->student;
    $product = $event->product;

    my_send_mail(
      array(
        'to' => $student->mail,
        'subject' => "SCHEDULE REMOVED | {$this->config->item('school_name')}",
        'message' => "
<p>Hi {$student->first_name},</p>
<p>The following session has been removed:</p>
<p><strong>Session: </strong> {$product->name}</p>
<p><strong>Reason: </strong>{$this->delete_reason_model->reason_value($event->description)}</p>
<p>Thank you!</p>
<p><strong>{$this->config->item('school_name_long')}</strong></p>
          "
      )
    );
  }

  private function _reschedule_mail_student($event, $new_schedules, $old_schedules)
  {
    $student = $event->student;

    $output_old = '';
    $output_new = '';

    foreach($old_schedules as $schedule)
    {
      $output_old .= "
      <p><strong>Start: {date('d/m/Y g:ia', $schedule->start)} - End: {date('d/m/Y g:ia', $schedule->end)}</strong></p>
      ";
    }

    foreach($new_schedules as $schedule)
    {
      $output_new .= "
      <p><strong>Start: {date('d/m/Y g:ia', $schedule->start)} - End: {date('d/m/Y g:ia', $schedule->end)}</strong></p>
      ";
    }
    my_send_mail(
      array(
        'to' => $student->mail,
        'subject' => "RESCHEDULED | {$this->config->item('school_name')}",
        'message' => "<p>Hi {$student->first_name},</p>
          <p>The following session has been rescheduled:</p>
          {$output_old}
          <p>The new session has been rescheduled for the following time:</p>
          {$output_new}
          <p><strong>{$this->config->item('school_name_long')}</strong></p>
          "
      )
    );
  }

  private function _cancel_mail_student($event, $old_schedule, $new_schedule)
  {
    $student = $event->student;

    my_send_mail(
      array(
        'to' => $student->mail,
        'subject' => "CANCELLATION NOTIFICATION | {$this->config->item('school_name')}",
        'message' => "
<p>Hi {$student->first_name},</p>
<p>Thank you for letting us know.</p>
<p>You have not been charged for the following cancellation:</p>
<p><strong>Start: {date('d/m/Y g:ia', $old_schedule->start)} - End: {date('d/m/Y g:ia', $old_schedule->end)}</strong></p>
<p>Your new lesson as been rescheduled for following time:<br />
<strong>Start: {date('d/m/Y g:ia', $new_schedule->start)} - End: {date('d/m/Y g:ia', $new_schedule->end)}</strong></p>
<p><strong>Reason: </strong>{$this->reason_model->reason_value($old_schedule->description)}</p>
<p>Thank you, </p>
<p><strong>{$this->config->item('school_name_long')}</strong></p>
          "
      )
    );
  }

  private function _cancel_under24_mail_student($event, $schedule)
  {
    $student = $event->student;

    my_send_mail(
      array(
        'to' => $student->mail,
        'subject' => "CANCELLATION NOTIFICATION | {$this->config->item('school_name')}",
        'message' => "
<p>Hi {$student->first_name},</p>
<p>This is a confirmation that you have cancelled under 24 hour notice.<p>
<p><strong>Reason: </strong>{$this->reason_model->reason_value($schedule->description)}
</p>
<p>Thank you,</p>
<p><strong>{$this->config->item('school_name_long')}</strong></p>
          "
      )
    );
  }

  private function _send_mail_student($event)
  {
    $student = $event->student;
    $product = $event->product;

    $studio = NULL;
    $teacher = NULL;

    $event_output = '';
    foreach($event->schedules as $i => $schedule)
    {
      if($i == 0) {
        $studio = $this->studio_model->studios($schedule->studio_id);
        $teacher = $this->user_model->staff_info($schedule->staff_id);
      }

      $event_output .= "
       <li>
        <h5>Session {$schedule->sequence}</h5>
        <span><strong>Start: </strong><em>{date('d/m/Y g:ia', $schedule->start)}</em> -
        <strong>End: </strong><em>{date('d/m/Y g:ia', $schedule->end)}</em></span>
       </li>
       ";
    }

    my_send_mail(
      array(
        'to' => $student->mail,
        'subject' => "RESERVATION | {$this->config->item('school_name')}",
        'message' => "
<p>Hi {$student->first_name},</p>
<p>Thank you for your enquiry and booking for a private singing lessons at $this->config->item('school_name')}.<br />
Please check the details of your reservation:</p>
<p><strong>Session</strong>: {$product->name}</p>
<p><strong>Status</strong>: Pending</p>
<p><strong>Studio</strong>: {$studio->street} {$studio->city} {$studio->postcode}</p>
<p><strong>Teacher</strong>: {$teacher->first_name} {$teacher->last_name}</p>
<p><strong>Mobile</strong>: {$teacher->mobile}</p>

<p>
  <h4>Sessions:</h4>
  <ul>$event_output</ul>
</p>

<p>Warm regards,</p>
          <p><strong>{$this->config->item('school_name_long')}</strong></p>
          "
      )
    );
  }

  private function _edit_lessons_send_mail_student($event, $edited_schedules)
  {
    $student = $this->user_model->student_info($event->student_id);

    $event_output = '';
    foreach($edited_schedules as $schedule)
    {
      $studio = $this->studio_model->studios($schedule->studio_id);
      $teacher = $this->user_model->staff_info($schedule->staff_id);
      $event_output .= "
       <li>
        <h3>Lesson {$schedule->sequence}</h3>
        <span><strong>Start: <em>{date('d/m/Y g:ia', $schedule->start)}</em> -
        End: </strong>{date('d/m/Y g:ia', $schedule->end)}</em></strong></span><br />
        <strong>Studio: </strong> {$studio->street} {$studio->city} {$studio->postcode}<br />
        <strong>Teacher: </strong> {$teacher->first_name} {$teacher->last_name}<br />
        <strong>Mobile: </strong> {$teacher->mobile}
       </li>
       ";
    }

    my_send_mail(
      array(
        'to' => $student->mail,
        'subject' => "LESSON UPDATE | {$this->config->item('school_name')}",
        'message' => "
<p>Hi {$student->first_name},</p>
<p>The following session have been updated:</p>
<ul>$event_output</ul>
<p>Thank you, </p>
<p><strong>{$this->config->item('school_name_long')}</strong></p>
          "
      )
    );
  }
}

/* End of file calendar.php */
/* Location: ./application/controllers/calendar.php */
